package gui_layer;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.DefaultCellEditor;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import javax.swing.plaf.ColorUIResource;
import javax.swing.table.TableCellEditor;

import model_layer.Customer;
import model_layer.Product;
import model_layer.Sale;
import model_layer.SaleLineItem;
import ctr_layer.CustomerCtr;
import ctr_layer.ProductCtr;
import ctr_layer.SaleCtr;
import ctr_layer.StaffMemberCtr;
/**
 * 
 * @author Rafal Markiewicz
 *
 */
public class NewSaleGUI extends SaleRestockNewWindow
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private DynamicSearchComboBoxModel dscbm_p;
	private Sale sale;
	private SaleCtr sale_ctr;
	private ProductCtr prod_ctr;
	private CustomerCtr cust_ctr;
	private JComboBox<String> prod_box;
	private boolean can_proceed;
	private boolean correct_amount;
	private boolean correct_product;
	private ProductAdder pa;
	private CustomerSetter cs;
	protected String[] column_names = {"ID", "Name", "Amount", "Price", "Total price"};

	/**
	 * Create the frame.
	 */
	public NewSaleGUI(Sale s)
	{
		super();
		
		JLabel lblCustomer = new JLabel("Customer");
		lblCustomer.setFont(new Font("Helvetica Neue", Font.BOLD, 11));
		lblCustomer.setForeground(Color.WHITE);
		search_set_panel.add(lblCustomer);
		
		
		sale = s;
		sale_ctr = new SaleCtr();
		cust_ctr = new CustomerCtr();
		prod_ctr = new ProductCtr();
		prepare_table(new Object[0][5], column_names);
		
		if(sale != null)
		{
			make_as_details();
			make_disocunt_lbl();
			this.setTitle("Sale Details");
			fill_data();
		}
		else
		{
			make_as_new();
			make_discount_button();
			this.setTitle("New Sale");
			start_work_on_new_sale();
		}
		
		this.addInternalFrameListener(new InternalFrameAdapter()
		{
			@Override
			public void internalFrameClosing(InternalFrameEvent arg0)
			{
				if(pa != null)
				{
					pa.dispose();
				}
				if(cs != null)
				{
					cs.dispose();
				}
				
			}
		});
	}
	
	private void fill_data()
	{
		set_box.setSelectedItem(sale.getCustomer().getName());
		MyTableModel mtm = (MyTableModel) table.getModel();
		Object[] data; 
		for (SaleLineItem item : sale.getItems())
		{
			data = new Object[5];
			data[0] = Integer.parseInt(item.getProduct().getId());
			data[1] = item.getProduct().getName();
			data[2] = item.getAmount();
			data[3] = item.getProduct().getPrice();
			data[4] = item.getPrice();
			mtm.addRow(data);
		}
		price_lbl.setText(String.valueOf(sale.getTotal_price()));
	}
	
	private void make_discount_button()
	{
		float[] values = Color.RGBtoHSB(255, 104, 0, null);
		JButton btnSetSpecialDisocunt = new JButton("Set special disocunt");
		btnSetSpecialDisocunt.setFont(new Font("Helvetica Neue", Font.BOLD, 11));
		btnSetSpecialDisocunt.setForeground(Color.WHITE);
		btnSetSpecialDisocunt.setBackground(Color.getHSBColor(values[0], values[1], values[2]));
		btnSetSpecialDisocunt.setContentAreaFilled(false);
		btnSetSpecialDisocunt.setOpaque(true);
		btnSetSpecialDisocunt.setBorder(new RoundedCornerBorder());
		btnSetSpecialDisocunt.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				set_special_discount();
				
			}
		});
		additional_button_panel.add(btnSetSpecialDisocunt);
	}
	
	private void make_disocunt_lbl()
	{
		JLabel lblSpecialDiscount = new JLabel("Special discount:");
		lblSpecialDiscount.setFont(new Font("Helvetica Neue", Font.BOLD, 11));
		lblSpecialDiscount.setForeground(Color.WHITE);
		additional_button_panel.add(lblSpecialDiscount);
		
		JLabel lblNewLabel = new JLabel(String.valueOf(sale.getSpecial_discount()));
		lblNewLabel.setFont(new Font("Helvetica Neue", Font.BOLD, 11));
		lblNewLabel.setForeground(Color.WHITE);
		additional_button_panel.add(lblNewLabel);
		JLabel lblpercent = new JLabel("%");
		lblpercent.setFont(new Font("Helvetica Neue", Font.BOLD, 11));
		lblpercent.setForeground(Color.WHITE);
		additional_button_panel.add(lblpercent);
	}
	
	private void start_work_on_new_sale()
	{
		prepare_table(new Object[1][5], column_names);

		can_proceed = false;
		sale = sale_ctr.make_new_sale();
		table.setRowSorter(null);
		set_box_bindings();
		
		set_table_bindings();
		set_dynamic_search_fields();
		set_editable_columns();
		dscbm.start_anew();
		set_box.configureEditor(set_box.getEditor(), "");
		set_box.requestFocus();
		price_lbl.setText("0.0");
	}
		
	
	private void set_box_bindings()
	{
		dscbm.set_all_data(get_all_customers_names());
		Component c = set_box.getEditor().getEditorComponent();
		c.addKeyListener(new KeyAdapter()
		{
			@Override
			public void keyPressed(KeyEvent e)
			{
				if (e.getKeyChar() =='\n')
				{
					set_customer();
					if (sale.getCustomer()!= null)
					{
						dscbm.set_handled(true);
						set_box.setBackground(Color.WHITE);
						set_box.setSelectedItem(sale.getCustomer().getName());
						price_lbl.setText(String.valueOf(sale.getTotal_price()));
						table.grabFocus();
						table.changeSelection(0, 1, false, false);
						if (table.editCellAt(0, 1))
				        {
				            Component editor = table.getEditorComponent();
				            editor.requestFocusInWindow();
				        }
						
						dscbm.set_handled(false);
					}
					else
					{
						set_box.setBackground(Color.RED);
					}
				}
			}
		});
		
		c.addFocusListener(new FocusAdapter()
		{
			@Override
			public void focusLost(FocusEvent e)
			{
				
				if(!dscbm.is_handled())
				{
					
					set_customer();
					if (sale.getCustomer()!= null)
					{
						price_lbl.setText(String.valueOf(sale.getTotal_price()));
						set_box.setBackground(Color.WHITE);
						set_box.setSelectedItem(sale.getCustomer().getName());
					}
					else
					{
						set_box.setBackground(Color.RED);
					}
				}
			}
		});
	}

	private void set_table_bindings()
	{
		InputMap map = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
		map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "strange go right");
		ActionMap a_map = table.getActionMap();
		a_map.put("strange go right", new AbstractAction()
		{
			/**
			 * 
			 */
			private static final long serialVersionUID = 1L;

			@Override
			public void actionPerformed(ActionEvent e)
			{
				System.out.println("Now it should change!");
				int row = table.getSelectedRow();
				int column = table.getSelectedColumn();
				if(column == 1)
				{
					table.editCellAt(row, column);
					Component comp = table.getEditorComponent();
			        comp.requestFocusInWindow();
				}
				row = table.convertRowIndexToModel(row);
				column = table.convertColumnIndexToModel(column);
				
				TableCellEditor editor = table.getCellEditor();
				if(editor != null)
				{
					editor.stopCellEditing();
				}
				else
				{
					
					perform_checks();
					
					
				}
				if(column == 1)
				{
					if(can_proceed)
					{
						table.editCellAt(row, column + 1);
						table.changeSelection(row, column +1, false, false);
					}
				}
				else if (column == 2)
				{
					if(can_proceed)
					{
						table.changeSelection(row + 1, 1, false, false);
						if (table.editCellAt(row + 1, 1))
				        {
				            Component comp = table.getEditorComponent();
				            comp.requestFocusInWindow();
				        }						
					}
				}
				can_proceed = false;
			}
		});
		
	}
	
	private void set_editor_options(TableCellEditor editor)
	{
		editor.addCellEditorListener(new CellEditorListener()
		{
			@Override
			public void editingStopped(ChangeEvent arg0)
			{
				if(!dscbm_p.is_handled())
				{
					
					perform_checks();
				}
			}
			@Override
			public void editingCanceled(ChangeEvent arg0)
			{
				// TODO Auto-generated method stub
				
			}
		});
	}
	
	private void set_dynamic_search_fields()
	{
		prod_box = new JComboBox<String>();
		
		prod_box.setEditable(true);
		dscbm_p = new DynamicSearchComboBoxModel(prod_box);
		List<String> data = get_all_prod_names();
		dscbm_p.set_all_data(data);
		prod_box.addItemListener(dscbm_p);
		prod_box.addKeyListener(dscbm_p);
		prod_box.setModel(dscbm_p);
		Component c = prod_box.getEditor().getEditorComponent();
		c.addKeyListener(new KeyAdapter()
		{
			@Override
			public void keyTyped(KeyEvent e)
			{
				System.out.println();
				if (e.getKeyChar() =='\n')
				{
					dscbm_p.set_handled(true);
					SaleLineItem item = check_correct_product();
					if(item != null)
					{
						int row = table.getSelectedRow();
						table.changeSelection(row, 2, false, false);
						table.editCellAt(row, 2);
						dscbm_p.start_anew();
						prod_box.configureEditor(prod_box.getEditor(), "");
						fill_row_with_item_data(item, row);
					}
					dscbm_p.set_handled(false);
				}
			}
		});
		table.getColumnModel().getColumn(1).setCellEditor(new ComboBoxCellEditor(prod_box));
		table.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(new JTextField()));
		ComboBoxCellEditor editor = (ComboBoxCellEditor) table.getColumnModel().getColumn(1).getCellEditor();
		set_editor_options(editor);
		DefaultCellEditor editor_d = (DefaultCellEditor) table.getColumnModel().getColumn(2).getCellEditor();
		set_editor_options(editor_d);
	}
	
	private void perform_checks()
	{
		int row = table.getSelectedRow();
		int column = table.getSelectedColumn();
		row = table.convertRowIndexToModel(row);
		column = table.convertColumnIndexToModel(column);
		SaleLineItem item = null;
		if(column == 1)
		{
			System.out.println("Performing product_check");
			item = check_correct_product();
			if(item!= null)
			{
				dscbm_p.start_anew();
				prod_box.configureEditor(prod_box.getEditor(), "");
			}
		}
		else if (column == 2)
		{
			System.out.println("Performing amount_check");
			item = check_correct_amount();			
		}
		
		if (item != null)
		{
			fill_row_with_item_data(item, row);
		}
		if(can_proceed)
		{
			if(correct_amount && correct_product)
			{
				item = sale_ctr.add_current_item();
				System.out.println("ADD CURRENT ITEM");
				if(item.getAmount() > item.getProduct().getQuantity())
				{
					MarkingCellRenderer renderer = (MarkingCellRenderer) table.getCellRenderer(row, 2);
					renderer.add_warning_cell(row);
					table.repaint();

				}
				MyTableModel mtm = (MyTableModel) table.getModel();
				correct_amount = false;
				correct_product = false;
				fill_row_with_item_data(item, row);
				mtm.addRow(new Object[5]);
			}
		}
		update_sale();
	}
	
	private SaleLineItem check_correct_amount()
	{

		can_proceed = false;
		int current_row = table.getSelectedRow();
		int current_column = table.getSelectedColumn();
		SaleLineItem item =null;
		if(current_row != -1)
		{
			current_row = table.convertRowIndexToModel(current_row);
			current_column = table.convertColumnIndexToModel(current_column);
			String amount = table.getModel().getValueAt(current_row, current_column).toString();
			String current_id = String.valueOf(table.getModel().getValueAt(current_row, current_column-2));
			boolean finished_cell = table.getModel().getValueAt(current_row, 4) != null;
			int i_amount = -1;
			System.out.println(amount);
			
			if(is_integer(amount))
			{
				i_amount = Integer.parseInt(amount);
				System.out.println(i_amount);
				can_proceed =  i_amount > 0;
			}
			MarkingCellRenderer renderer = (MarkingCellRenderer) table.getCellRenderer(current_row, current_column);
			if(can_proceed)
			{
				if(finished_cell)
				{
					item = sale_ctr.update_amount(current_id, i_amount);
					System.out.println("UPDATE AMOUNT");
					if(item.getProduct().getQuantity() < item.getAmount())
					{
							renderer.add_warning_cell(current_row);
							renderer.remove_incorrect_cell(current_row);
							table.repaint();
					}
					else
					{
						renderer.remove_incorrect_cell(current_row);
						renderer.remove_warning_cell(current_row);
						table.repaint();
					}
				}
				else
				{
					correct_amount = true;
					sale_ctr.set_amount(i_amount);
					System.out.println("SET AMOUNT");
					renderer.remove_incorrect_cell(current_row);
					renderer.remove_warning_cell(current_row);
					table.repaint();
				}
			}
			else
			{
				if(!finished_cell)
				{
					correct_amount = false;
				}
				renderer.add_incorrect_cell(current_row);
				renderer.remove_warning_cell(current_row);
				table.repaint();
			}
		}
		return item;
	}
	
	private SaleLineItem check_correct_product()
	{

		int current_row = table.getSelectedRow();
		int current_column = table.getSelectedColumn();
		can_proceed = false;
		SaleLineItem item = null;
		
		if(current_row != -1)
		{
			current_row = table.convertRowIndexToModel(current_row);
			current_column = table.convertColumnIndexToModel(current_column);
			
			//String value = (String)c.get_item();
			//System.out.println("Cell editor value: " + value);
			String id_name = (String) prod_box.getEditor().getItem();
			
			prod_box.setSelectedItem(id_name);
			System.out.println("Product data: " + id_name);
			String old_id = String.valueOf(table.getModel().getValueAt(current_row, current_column-1));
			
			boolean finished_row = table.getModel().getValueAt(current_row, 4) != null;
			if(finished_row)
			{
				if(is_integer(id_name))
				{
					item = sale_ctr.update_product_by_id(old_id, id_name);
					System.out.println("UPDATE PRODUCT BY ID");
				}
				else
				{
					item = sale_ctr.update_product_by_name(old_id, id_name);
					System.out.println("UPDATE PRODUCT BY NAME");
				}
			}
			else
			{
				if(is_integer(id_name))
				{
					item = sale_ctr.set_product_by_id(id_name);
					System.out.println("SET PRODUCT BY ID");
				}
				else
				{
					item = sale_ctr.set_product_by_name(id_name);
					System.out.println("SET PRODUCT BY NAME");
				}
				if(item!=null)
				{
					correct_product = true;
				}
				else
				{
					correct_product = false;
				}
			}
			can_proceed = item != null;
			MarkingCellRenderer renderer = (MarkingCellRenderer) table.getCellRenderer(current_row, current_column);
			if (!can_proceed)
			{
				renderer.add_incorrect_cell(current_row);
				table.repaint();
			}
			else
			{
				renderer.remove_incorrect_cell(current_row);
			}
		}
		return item;
	}
	
	private void update_sale()
	{
		sale = sale_ctr.get_current_sale();
		price_lbl.setText(String.valueOf(sale.getTotal_price()));
	}
	
	
	private void fill_row_with_item_data(SaleLineItem item, int row)
	{
		MyTableModel model = (MyTableModel) table.getModel();
		model.setValueAt(Integer.parseInt(item.getProduct().getId()), row, 0);
		model.setValueAt(item.getProduct().getName(), row, 1);
		model.setValueAt(item.getProduct().getPrice(), row, 3);
		if(item.getAmount() != 0)
		{
			model.setValueAt(item.getAmount(), row, 2);
			if(item.getPrice() != 0)
			{
				model.setValueAt(item.getPrice(), row, 4);
			}
		}
	}
	
	private void fill_last_row_with_item_data(SaleLineItem item)
	{
		int last_row = table.getModel().getRowCount() - 1;
		fill_row_with_item_data(item, last_row);
		MarkingCellRenderer mcr = (MarkingCellRenderer) table.getCellRenderer(last_row, 2);
		if(item.getAmount() != 0)
		{
			mcr.remove_incorrect_cell(last_row);
			if(item.getAmount() > item.getProduct().getQuantity())
			{
				mcr.add_warning_cell(last_row);
			}
			else
			{
				mcr.remove_warning_cell(last_row);
			}
			table.repaint();
		}
		mcr = (MarkingCellRenderer) table.getCellRenderer(last_row, 1);
		mcr.remove_incorrect_cell(last_row);
	}
		
	private void set_customer()
	{
		String cust_data = (String) set_box.getEditor().getItem();
		set_box.setSelectedItem(cust_data);
		System.out.println(cust_data);
		if(cust_data.length() == 0)
		{
			sale = sale_ctr.set_customer_with_id("0");
		}
		else if (is_integer(cust_data))
		{
			sale = sale_ctr.set_customer_with_id(cust_data);
		}
		else
		{
			sale = sale_ctr.set_customer_with_name(cust_data);
		}
		
	}
	
	private boolean is_everything_ok()
	{
		if(set_box.getBackground().equals(Color.RED) || sale.getCustomer() == null)
		{
			return false;
		}
		int rows = table.getModel().getRowCount();
		if(rows-1 == 0)
		{
			return false;
		}
		for(int i = 0; i < rows-1; i++)
		{
			Component cell1 = table.prepareRenderer(table.getCellRenderer(i, 1), i, 1);
			Component cell2 = table.prepareRenderer(table.getCellRenderer(i, 2), i, 2);
			if(cell1.getBackground().equals(Color.RED) || cell2.getBackground().equals(Color.RED))
			{
				return false;
			}
		}
		return true;
	}
	
	private boolean is_last_row_empty()
	{
		int last_row = table.getModel().getRowCount() - 1;
		return (table.getModel().getValueAt(last_row, 1) == null || table.getModel().getValueAt(last_row, 1).equals(""))
				&& (table.getModel().getValueAt(last_row, 2) == null || table.getModel().getValueAt(last_row, 2).equals(""));
		
	}
	
	private List<String> get_all_prod_names()
	{

		List<Product> products = prod_ctr.find_non_deleted_products();
		List<String> names_ids = new ArrayList<String>();
		for(Product prod : products)
		{
			names_ids.add(prod.getName());
		}
		return names_ids;
	}
	
	private List<String> get_all_customers_names()
	{
		List<String> ids_names = new ArrayList<String>();
		List<Customer> customers = cust_ctr.find_non_deleted_customers();
		for(Customer cust : customers)
		{
			ids_names.add(cust.getName());
		}
		return ids_names;
	}
	
	private void set_special_discount()
	{
		if(CurrentAccount.get_privilage_level() == 0)
		{
			JTextField manager_login = new JTextField();
			JPasswordField manager_password = new JPasswordField();
			Object[] message = { "Manager login" , manager_login, "Manager password", manager_password };
			if(JOptionPane.showConfirmDialog(null, message, "Set discount", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION)
			{
				StaffMemberCtr sm_ctr = new StaffMemberCtr();
				if(sm_ctr.log_in_staff_member(manager_login.getText(), String.valueOf(manager_password.getPassword())) != null)
				{
					boolean end = false;
					do
					{
						String discount = JOptionPane.showInputDialog(this, "Input discount in percents.");
						if(discount != null)
						{
							
							Sale s = sale_ctr.make_special_discount(discount);
							if(s != null)
							{
								price_lbl.setText(String.valueOf(s.getTotal_price()));
								end = true;
							}
							else
							{
								end = (JOptionPane.showConfirmDialog(this, "Discount not typed properly.\n"
										+ "Do you wish to insert it again?", "Incorrect", JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION);
							}
						}
						else
						{
							end = true;
						}
					} while(!end);	
				}
				else
				{
					JOptionPane.showMessageDialog(this, "Incorrect login or password", "Incorrect", JOptionPane.ERROR_MESSAGE);
				}
			}
		}
		else
		{
			boolean end = false;
			do
			{
				String discount = JOptionPane.showInputDialog(this, "Input discount in percents.");
				if(discount != null)
				{
					Sale s = sale_ctr.make_special_discount(discount);
					if(s != null)
					{
						price_lbl.setText(String.valueOf(s.getTotal_price()));
						end = true;
					}
					else
					{
						end = (JOptionPane.showConfirmDialog(this, "Discount not inserted properly.\n"
								+ "Do you wish to insert it again?", "Incorrect", JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION);
					}
				}
				else  end = true;
			} while(!end);	
		}
	}

	@Override
	protected void search()
	{

		cs = new CustomerSetter();
		this.getDesktopPane().add(cs);
		Point window_corner = this.getLocation();
		cs.setLocation((int) window_corner.getX() + 15, (int) window_corner.getY() + 15);
		cs.setVisible(true);
		
	}

	@Override
	protected void add_product()
	{
		pa = new ProductAdder();
		this.getDesktopPane().add(pa);
		Point window_corner = this.getLocation();
		pa.setLocation((int) window_corner.getX() + 15, (int) window_corner.getY() + 15);
		pa.setVisible(true);		
	}

	@Override
	protected void save()
	{
		if(is_everything_ok())
		{
			boolean save;
			if(is_last_row_empty())
			{
				save = JOptionPane.showConfirmDialog(this, "Are you sure you want to save the sale?\n ", 
						"Save sale?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
			}
			else
			{
				save = JOptionPane.showConfirmDialog(this, "Are you sure you want to save the sale?\n "
						+ "The last row is not empty, it will however, not be saved since it wasn't entered fully.\n"
						+ "Continuing will save the sale without last row.", "Save sale?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
			}
			while(save)
			{
				int rc = sale_ctr.save_sale(CurrentAccount.get_instance().get_current_account());
				if(rc == 1)
				{
					if(!sale.getCustomer().getId().equals("0"))
					{
						if(JOptionPane.showConfirmDialog(this, "Do you wish to print an invoice? \n",
								"Print invoice?", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
						{
							InvoicePrinter ip = new InvoicePrinter(sale);
							ip.print();
						}
					}
					/*if(JOptionPane.showConfirmDialog(this, "Sale was saved successfully! \n"
							+ "Do you wish to make a new sale?","Success!", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
					{*/
					start_work_on_new_sale();
					save = false;
					/*}
					else
					{
						dispose();
						fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
					}*/
					
				}
				else if(rc == -1)
				{
					
					save = JOptionPane.showConfirmDialog(this, "An error occured while adding a sale. \n"
							+ "Do you wish to try again?", "Error", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
				}
				else if(rc == -2)
				{
					JOptionPane.showMessageDialog(this, "Sale cannot be added because some of the products ran out of stock while making the sale. "
							,"Cannot add sale", JOptionPane.ERROR_MESSAGE);
					save = false;
				}
				
			}
		}
		else
		{
			JOptionPane.showMessageDialog(this, "Sale cannot be added because some data were typed incorrectly, "
					+ "or no products were added.","Cannot add sale", JOptionPane.ERROR_MESSAGE);
		}
	}

	@Override
	protected void delete()
	{
		int row = table.getSelectedRow();
		int last_row = table.getRowCount() - 1;
		if(row != -1)
		{
			row = table.convertRowIndexToModel(row);
			last_row = table.convertRowIndexToModel(last_row);
			if(!(row == last_row))
			{
				if(JOptionPane.showConfirmDialog(this, "Are you sure you wish to remove this product from sale?",
						"Remove product", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
				{
					MyTableModel mtm = (MyTableModel) table.getModel();
					String id = mtm.getValueAt(row, 0).toString();
					sale_ctr.remove_product(id);
					TableCellEditor editor = table.getCellEditor();
					if(editor != null)
					{
						editor.stopCellEditing();
					}
					
					mtm.removeRow(row);
					
				}
			}
			else
			{
				MyTableModel mtm = (MyTableModel) table.getModel();
				mtm.removeRow(last_row);
				mtm.addRow(new Object[5]);
				correct_product = false;
				correct_amount = false;
			}
			MarkingCellRenderer mcr = (MarkingCellRenderer) table.getCellRenderer(row, 1);
			mcr.revalidate_after_delete(row);
			mcr = (MarkingCellRenderer) table.getCellRenderer(row, 2);
			mcr.revalidate_after_delete(row);
			table.repaint();
			sale = sale_ctr.get_current_sale();
			price_lbl.setText(String.valueOf(sale.getTotal_price()));
		}
		
	}

	@Override
	protected void set_editable_columns()
	{
		MyTableModel mtm = (MyTableModel) table.getModel();
		mtm.add_editable_column(1);
		mtm.add_editable_column(2);
		table.getColumnModel().getColumn(1).setCellRenderer(new MarkingCellRenderer());
		table.getColumnModel().getColumn(2).setCellRenderer(new MarkingCellRenderer());
	}
	
	private void add_row()
	{
		MyTableModel mtm = (MyTableModel) table.getModel();
		mtm.addRow(new Object[5]);
		correct_product = false;
		correct_amount = false;
		update_sale();
	}
	
	private void cancel_last_row_edit()
	{
		table.getCellEditor(table.getRowCount() - 1, 1).cancelCellEditing();;
		table.getCellEditor(table.getRowCount() - 1, 2).cancelCellEditing();
	}
	
	class ProductAdder extends AddProductGUI
	{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public ProductAdder()
		{
			super();
		}
		
		@Override
		protected void set_or_add()
		{
			int row = table.getSelectedRow();
			if(row != -1)
			{
				row = table.convertRowIndexToModel(row);
				String id = String.valueOf(table.getModel().getValueAt(row, 0));
				System.out.println(id);
				SaleLineItem item = sale_ctr.set_product_by_id(id);
				if(item != null)
				{
					cancel_last_row_edit();
					dscbm_p.start_anew();
					prod_box.configureEditor(prod_box.getEditor(), "");
					fill_last_row_with_item_data(item);
					correct_product = true;
					boolean end = false;
					while(!end)
					{
						String amount = JOptionPane.showInputDialog(this, "Please input amount of product");
						if(amount == null)
						{
							end = true;
						}
						else
						{
							if(is_integer(amount))
							{
								int i_amount = Integer.parseInt(amount);
								if(i_amount > 0)
								{
									sale_ctr.set_amount(i_amount);
									item = sale_ctr.add_current_item();
									fill_last_row_with_item_data(item);
									add_row();
									end = true;
								}
								else
								{
									JOptionPane.showMessageDialog(this, "Amount must be greater than 0.", "Incorrect amount", JOptionPane.ERROR_MESSAGE);
								}
							}
							else
							{
								JOptionPane.showMessageDialog(this, "Amount must be a number.", "Incorrect amount", JOptionPane.ERROR_MESSAGE);
							}
						}
					}
				}
				else
				{
					JOptionPane.showMessageDialog(this, "The product was already added!\nChoose a different one.",
							"Product already present", JOptionPane.PLAIN_MESSAGE);
				}
			}
		}
	}
	
	class CustomerSetter extends SetCustomerGUI
	{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public CustomerSetter()
		{
			super();
		}
		
		@Override
		protected void set_or_add()
		{
			{
				int row = table.getSelectedRow();
				if(row != -1)
				{
					row = table.convertRowIndexToModel(row);
					String id = String.valueOf(table.getModel().getValueAt(row, 0));
					System.out.println(id);
					sale = sale_ctr.set_customer_with_id(id);
					if(sale.getCustomer() != null)
					{
						set_box.setSelectedItem(sale.getCustomer().getName());
						set_box.setBackground(Color.WHITE);
					}
					this.dispose();
					
				}
			}
		}
		
	}
}
